package com.yeyks.controller.activity;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yeyks.account.dal.domain.AccountInfo;
import com.yeyks.annotation.NeedToken;
import com.yeyks.common.ajax.AjaxResponseBody;
import com.yeyks.common.base.Arguments;
import com.yeyks.common.constants.AccountType;
import com.yeyks.common.constants.OrderStatus;
import com.yeyks.common.exception.ServiceException;
import com.yeyks.common.utils.DateUtils;
import com.yeyks.common.utils.RedisUtil;
import com.yeyks.common.utils.apputil.rediskey.RedisKey;
import com.yeyks.commonReference.append.sms.SmsService;
import com.yeyks.commonReference.service.order.OrderHeadService;
import com.yeyks.commonReference.service.other.CouponInfoService;
import com.yeyks.consumer.dal.domain.UserCouponPush;
import com.yeyks.consumer.dal.domain.UserInfo;
import com.yeyks.consumer.dal.domain.UserLoginHistory;
import com.yeyks.consumer.service.UserCouponPushService;
import com.yeyks.consumer.service.UserInfoService;
import com.yeyks.consumer.service.UserLoginHistoryService;
import com.yeyks.order.dal.domain.OrderHead;
import com.yeyks.other.dal.domain.CouponDayNoOrder;
import com.yeyks.other.dal.domain.CouponInfo;
import com.yeyks.other.service.CouponDayNoOrderService;
import com.yeyks.web.AccountUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "V4.3.0 优惠券列表触发 短信发送")
@RestController
@RequestMapping("/coupon/sms")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CouponSMSController {

    private final UserLoginHistoryService userLoginHistoryService;

    private final OrderHeadService orderHeadService;

    private final UserInfoService userInfoService;

    private final SmsService smsService;

    private final CouponInfoService couponInfoService;

    private final CouponDayNoOrderService  couponDayNoOrderService;

    private final UserCouponPushService userCouponPushService;

    private final RedisUtil redisUtil;
    //1.查询 【某时间区间内】 首次登陆的用户
    private static final HashMap<Integer, String> userIdAndPhoneMap = Maps.newHashMap();

    static {
        //默认加一条自己的优惠券
        userIdAndPhoneMap.put(19878, "18582131913");
        userIdAndPhoneMap.put(19996, "15051868420");
        userIdAndPhoneMap.put(19997, "18329159427");
        userIdAndPhoneMap.put(20012, "13185008511");
    }

    @ApiOperation(value = "V4.3.0 查询 【某时间区间内】 首次登陆的用户", response = UserInfo.class)
    @NeedToken
    @PostMapping("/query/user")
    public AjaxResponseBody<List<UserInfo>> queryFirstLoginByDay(
            @RequestParam(value = "someDay", required = true) Integer someDay
    ){
        AccountInfo loginUser = AccountUtils.getLoginUser();
        if (loginUser.getType() != AccountType.Administrator) {
            throw new ServiceException("没有权限操作");
        }
        AjaxResponseBody body = AjaxResponseBody.failed();
        Date date = DateUtils.dayBefore(someDay);
        Date endDate = DateUtils.setTimeToMax(date);
        Date startDate = DateUtils.setTimeToZero(date);
        List<UserLoginHistory> userLoginHistoryList = userLoginHistoryService
                .queryFirstLoginByDay(startDate, endDate);
        if(!CollectionUtils.isEmpty(userLoginHistoryList)){
            userLoginHistoryList.forEach(userLoginHistory -> {
                userIdAndPhoneMap.put(userLoginHistory.getUserId(), userLoginHistory.getPhone());
            });
            List<Integer> userIds = userLoginHistoryList.stream().map(UserLoginHistory::getUserId)
                    .distinct().collect(Collectors.toList());
            userIds.addAll(userIdAndPhoneMap.keySet());
            List<Integer> sendUserIds = this.filterOrderIsZero(userIds, someDay);
            body = AjaxResponseBody.success(userInfoService.listByIds(sendUserIds));
        }
        return body;
    }

    //2.根据用户ID集合 查询 【某时间区间内】 订单的完成数量，如果数量为 0， 记录该用户ID， phone信息。

    private List<Integer> filterOrderIsZero(List<Integer> userIds,
                                            Integer someDay){
        List<Integer> zeroUserId = Lists.newArrayList();
        Collection<CouponInfo> couponInfoCollection = getCouponList(someDay);
        if(CollectionUtils.isEmpty(couponInfoCollection)){
            throw new ServiceException("该天数的优惠券为空！！");
        }
        Date now = new Date();
        int sumPrice = couponInfoCollection.stream().mapToInt(CouponInfo::getPrice).sum()/100;
        if(!CollectionUtils.isEmpty(userIds)){
            userIds.forEach(userId -> {
                int count = orderHeadService.count(new QueryWrapper<OrderHead>()
                        .eq(OrderHead.USER_ID, userId)
                        .eq(OrderHead.STATUS, OrderStatus.postCheckOut)
                        .between(OrderHead.GMT_CREATE, now, DateUtils.dayBefore(someDay)));
                if(count == 0){
                    //3.根据 筛选结果的 用户phone信息， 发送【某时间区间内】的短信模板， 期间先将对应的 优惠券发送给用户。
                    zeroUserId.add(userId);
                    String phone = userIdAndPhoneMap.get(userId);
                    if(Arguments.strNotNull(phone)){
                        //发送短信
                        boolean flag = smsService.sendSmsToUserAboutOrderIsZeroBySomeDay(phone, sumPrice);
                    }
                }
            });
            //发送优惠券(批量发送及 之前的 [推送])
            savePushCoupon(zeroUserId, couponInfoCollection.stream().map(CouponInfo::getId).collect(Collectors.toList()));

        }
        return zeroUserId;
    }

    /**
     * 实现优惠券推送
     * @param userIds 用户集合
     * @param couponIds 优惠券集合
     */
    private void savePushCoupon(List<Integer> userIds, List<Integer> couponIds){
        UserCouponPush couponPush = new UserCouponPush();
        couponPush.setTitle("新人无完成订单（免费优惠券）");
        couponPush.setPushStartTime(new Date());
        //2070-02-21 18:15:35的时间戳
        couponPush.setPushEndTime(DateUtils.stampToYMDHMSDate(3160203335000L));
        if (userIds.size() < 2000) {
            couponPush.setUserIdJson(userIds.toString());
        } else {
            couponPush.setUserIdJson("具体查看Redis缓存");
        }
        couponPush.setCouponIdJson(JSON.toJSONString(couponIds));
        boolean save = userCouponPushService.save(couponPush);
        if (save) {
            String key = RedisKey.COUPON_PUSH_KEY_USER_ID + couponPush.getId();
            HashMap<String, Object> map = Maps.newHashMap();
            for(Integer userId : userIds){
                map.put(String.valueOf(userId), userIdAndPhoneMap.get(userId));
            }
            redisUtil.hset(key, map);
        }
    }

    /**
     * 根据天数得到需要发送 优惠券的集合
     * @param someDay 天数
     * @return 返回
     */
    private Collection<CouponInfo> getCouponList(Integer someDay){
        CouponDayNoOrder couponDayNoOrder = couponDayNoOrderService.getOne(new QueryWrapper<CouponDayNoOrder>()
                .eq(CouponDayNoOrder.SOME_DAY, someDay));
        if(null != couponDayNoOrder && Arguments.strNotNull(couponDayNoOrder.getCouponIds())){
            return couponInfoService.listByIds(Arrays.asList(couponDayNoOrder.getCouponIds().split(",")));
        }
        return null;
    }

    //定时任务最后调用。 （条件互斥）。
}
